/* 
 * File:   Mean.cpp
 * Author: Gab'z
 * 
 * Created on 4 juin 2012, 23:20
 */

#include "Mean.h"
#include "../../literal/Integer.h"
#include "../../literal/Number.h"

namespace calculator {

    Mean::Mean(const std::string name) : NaryOperator(name) {
    }

    Mean::Mean(const Mean& orig) : NaryOperator(orig._name) {
    }

    Mean::~Mean() {
    }

    Mean* Mean::clone() const {
        return new Mean(_name);
    }

    const Number* Mean::apply(const Stack* stack) const throw (ArithmeticException) {
        if (stack->size() == 0) throw CommandException("Empty stack");
        Number* resNumber = new Integer(0);
        for (unsigned int i = 0; i < stack->size(); i++) {
            const Number* loopNumber = dynamic_cast<const Number*> (stack->getConstant(i));
            if (loopNumber == 0) {
                std::ostringstream oss;
                oss << "NaN : " << ((stack->getConstant(i) != 0) ? stack->getConstant(i)->toString() : "EmptyStack");
                throw ArithmeticException(oss.str());
            }
            Number* loopResNumber;
            try {
                loopResNumber = add(resNumber, loopNumber);
            } catch (ArithmeticException& e) {
                throw;
            }
            delete resNumber;
            resNumber = loopResNumber;
        }
        const Integer* integer = new Integer(stack->size());
        Number* tmpResNumber;
        try {
            tmpResNumber = div(resNumber, integer);
        } catch (ArithmeticException& e) {
            delete integer;
            throw;
        }
        delete resNumber;
        resNumber = tmpResNumber;

        return resNumber;
    }
}